require("./common")

// 监听 mock 目录（/mock，而不是 /src/mock）。
// const chokidar = require('chokidar')
const path = require('path')

const Mock = require('mockjs')
const bodyParser = require('body-parser')

// 绝对路径
const mockDir = path.join(process.cwd(), 'mock'+ path.sep + 'test')

// 处理各个模块监听的路由和响应
const responseFake = (url, type, respond) => {
  return {
    url: new RegExp(`${process.env.VUE_APP_BASE_API_CONTEXT}${url}`),
    type: type || 'get',
    response(req, res) {
      console.log('request invoke: ' + req.path)
      res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
    }
  }
}

// 监听各个接口（这里，mock 下的各个模块内不需要监听了，而是在这个函数内统一处理）
function registerMockRoutes(app) {
  var mockRoutesLastIndex = 0;
  var mockRoutesLength = 0;
  /*
  这里必须注意：当前使用 nodejs 8.9.4，对 ES6 支持不全，比如会报错 import 不支持等。
  这需要先 require('@babel/register')，然后才能使用。
  所以，把 require('@babel/register') 放在了 module.exports 内调用 registerMockRoutes(app) 的前面。
  ERROR  Error loading vue.config.js:
  ERROR  SyntaxError: Unexpected token import
  E:\study\study-js-vue\vue2\taibiquan\mock\test\index.js:1
  (function (exports, require, module, __filename, __dirname) { import admin from './admin'
                                                               ^^^^^^

  SyntaxError: Unexpected token import
     at createScript (vm.js:80:10)
     at Object.runInThisContext (vm.js:139:10)
     at Module._compile (module.js:607:28)
     at Object.Module._extensions..js (module.js:654:10)
     at Module.load (module.js:556:32)
     at tryModuleLoad (module.js:499:12)
     at Function.Module._load (module.js:491:3)
     at Module.require (module.js:587:17)
     at require (internal/module.js:11:18)
     at Object.<anonymous> (E:\study\study-js-vue\vue2\taibiquan\mock\index.js:7:20)
  */
  const mockRoutes = require("./test")
  // console.log('mockRoutes', mockRoutes);

  // 最终监听的各个路由
  var finalMockRoutes = mockRoutes.map( route => {
    return responseFake(route.url, route.type, route.response)
  })

  // 监听
  for (var mockRoute of finalMockRoutes) {
    app[mockRoute.type](mockRoute.url, mockRoute.response)
    // 每监听一个URL，app._router.stack.length 就会 +1。
    mockRoutesLastIndex = app._router.stack.length
    mockRoutesLength++
  }

  return {
    mockRoutesLength,
    // 计算第一个自定义的 mock URL 在 app._router.stack 的索引。
    mockRoutesStartIndex: mockRoutesLastIndex - mockRoutesLength
  }
}

// 取消监听
function unregisterMockRoutes() {
  Object.keys(require.cache).forEach(i => {
    if (i.includes(mockDir)) {
      delete require.cache[require.resolve(i)]
    }
  })
}

module.exports = function (app) {
  console.log("/mock/index.js module.exports >> process.env.VUE_APP_API_MOCK", process.env.VUE_APP_API_MOCK);

  // es6 polyfill
  // 只有这样，后续的代码中才支持 import 等 ES6 语法。比如 require("./test") 中 ./test/index.js 内使用 import。
  require('@babel/register')

  app.use(bodyParser.json())
  // app.use(bodyParser.urlencoded({
  //   extended: true
  // }))

  const mockRoutesData = registerMockRoutes(app)
  var mockRoutesLength = mockRoutesData.mockRoutesLength
  var mockRoutesStartIndex = mockRoutesData.mockRoutesStartIndex

  // 监听 mock 的变化
  // chokidar.watch(mockDir, {
  //   ignored: /mock-env/,
  //   ignoreInitial: true
  // }).on('all', (event, path) => {
  //   if (event === 'change' || event === 'add') {
  //     try {
  //       // remove mock routes stack
  //       app._router.stack.splice(mockRoutesStartIndex, mockRoutesLength)
  //
  //       // 清理 mock 路由缓存
  //       unregisterMockRoutes()
  //
  //       const mockRoutesData2 = registerMockRoutes(app)
  //       mockRoutesLength = mockRoutesData2.mockRoutesLength
  //       mockRoutesStartIndex = mockRoutesData2.mockRoutesStartIndex
  //
  //       console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed  ${path}`))
  //     } catch (error) {
  //       console.log(chalk.redBright(error))
  //     }
  //   }
  // })
};
